// 获取canvas元素
const canvas = document.querySelector('canvas');
// 获取canvas的2d绘图上下文
const ctx = canvas.getContext('2d');

/**
 * 初始化canvas
 * @description devicePixelRatio: 设备像素比 (设备像素 / 物理像素) (缩放比)
 */
function init() {
    canvas.width = window.innerWidth * devicePixelRatio;
    canvas.height = window.innerHeight * devicePixelRatio;
}

init();

/**
 * 获取一个指定范围内的随机整数
 * @param {number} min - 最小值
 * @param {number} max - 最大值
 * @returns {number} 随机整数
 */
function getRandom(min, max) {
    // 使用Math.random()生成一个0到1之间的随机数
    // 将随机数乘以(max - min + 1)得到一个最大值为(max - min + 1)的随机数
    // 使用Math.floor()将随机数向下取整，得到一个整数
    // 将整数加上min，得到一个在[min, max]范围内的随机整数
    return Math.floor(Math.random() * (max - min + 1) + min);
}

class Point {
    constructor() {
        // 设置半径
        this.r = 4;
        // 设置随机x坐标和y坐标
        this.x = getRandom(0, canvas.width - this.r / 2);
        this.y = getRandom(0, canvas.height - this.r / 2);
        // 设置x轴速度和y轴速度
        this.xSpeed = getRandom(-50, 50);
        this.ySpeed = getRandom(-50, 50);
        // 上一次绘制时间
        this.lastDrawTime = null;
    }
    // 绘制方法
    draw() {
        // 更新坐标
        if (this.lastDrawTime) {
            // 计算新的坐标
            const duration = (Date.now() - this.lastDrawTime) / 1000;
            const xDis = this.xSpeed * duration;
            const yDis = this.ySpeed * duration;
            let x = this.x + xDis,
                y = this.y + yDis;
            // 边界处理
            if (x > canvas.width - this.r / 2) {
                x = canvas.width - this.r / 2;
                this.xSpeed = -this.xSpeed;
            } else if (x < 0) {
                x = 0;
                this.xSpeed = -this.xSpeed;
            }
            if (y > canvas.height - this.r / 2) {
                y = canvas.height - this.r / 2;
                this.ySpeed = -this.ySpeed;
            } else if (y < 0) {
                y = 0;
                this.ySpeed = -this.ySpeed;
            }
            // 更新坐标
            this.x = x;
            this.y = y;
        }
        ctx.beginPath();
        ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
        ctx.fillStyle = 'rgb(200,200,200)';// 设置填充颜色为灰色
        ctx.fill();// 填充圆形
        // 记录当前时间，用于下次更新坐标
        this.lastDrawTime = Date.now();
    }
}

class Graph {
    /**
     * 图形类
     * @param {number} pointNumber 点的数量，默认为30
     * @param {number} maxDis 最大距离，默认为500
     */
    constructor(pointNumber = 30, maxDis = 500) {
        this.points = new Array(pointNumber).fill(0).map(() => new Point());
        this.maxDis = maxDis;
    }

    /**
     * 绘制图形
     */
    draw() {
        // 画好后再画一遍
        requestAnimationFrame(() => {
            this.draw();
        });

        // 清空画布
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // 遍历所有点
        for (let i = 0; i < this.points.length; i++) {
            const p1 = this.points[i];
            p1.draw();

            // 遍历其他点
            for (let j = 0; j < this.points.length; j++) {
                const p2 = this.points[j];
                const d = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
                if (d > this.maxDis) {
                    continue;
                }

                // 绘制线段
                ctx.beginPath();
                ctx.moveTo(p1.x, p1.y);
                ctx.lineTo(p2.x, p2.y);
                ctx.closePath();
                ctx.strokeStyle = `rgba(200,200,200,${1 - d / this.maxDis})`;
                ctx.stroke();
            }
        }
    }
}

const g = new Graph();
g.draw();